import axios, {
  AxiosError,
  AxiosInstance,
  AxiosRequestConfig,
  AxiosResponse,
  InternalAxiosRequestConfig,
} from "axios";

// 响应数据接口
interface ApiResponse<T = unknown> {
  code: number;
  message: string;
  data: T;
  success: boolean;
}

// 请求配置接口
interface RequestConfig extends AxiosRequestConfig {
  showLoading?: boolean;
  showError?: boolean;
}

// 单例模式Request类
class Request {
  private static instance: Request;
  private axiosInstance: AxiosInstance;
  private loadingCount: number = 0;

  private constructor() {
    // 创建axios实例
    this.axiosInstance = axios.create({
      baseURL:
        process.env.NODE_ENV === "production"
          ? "https://api.yourdomain.com"
          : "http://localhost:3000/api",
      timeout: 10000,
      headers: {
        "Content-Type": "application/json",
      },
    });

    // 设置请求拦截器
    this.setupRequestInterceptors();

    // 设置响应拦截器
    this.setupResponseInterceptors();
  }

  // 获取单例实例
  public static getInstance(): Request {
    if (!Request.instance) {
      Request.instance = new Request();
    }
    return Request.instance;
  }

  // 设置请求拦截器
  private setupRequestInterceptors(): void {
    this.axiosInstance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        // 添加token到请求头
        const token = this.getToken();
        if (token && config.headers) {
          config.headers.Authorization = `Bearer ${token}`;
        }

        // 显示loading
        if ((config as RequestConfig).showLoading !== false) {
          this.showLoading();
        }

        // 添加时间戳防止缓存
        if (config.method === "get") {
          config.params = {
            ...config.params,
            _t: Date.now(),
          };
        }

        console.log("🚀 请求拦截器:", {
          url: config.url,
          method: config.method,
          data: config.data,
          params: config.params,
        });

        return config;
      },
      (error: AxiosError) => {
        console.error("❌ 请求拦截器错误:", error);
        this.hideLoading();
        return Promise.reject(error);
      },
    );
  }

  // 设置响应拦截器
  private setupResponseInterceptors(): void {
    this.axiosInstance.interceptors.response.use(
      (response: AxiosResponse<ApiResponse>) => {
        // 隐藏loading
        this.hideLoading();

        console.log("✅ 响应拦截器:", {
          url: response.config.url,
          status: response.status,
          data: response.data,
        });

        const { data, status } = response;

        // 处理HTTP状态码
        if (status >= 200 && status < 300) {
          // 处理业务状态码
          if (data.success === false) {
            this.handleBusinessError(data);
            return Promise.reject(new Error(data.message || "业务处理失败"));
          }
          return data;
        }

        return Promise.reject(new Error(`HTTP错误: ${status}`));
      },
      (error: AxiosError<ApiResponse>) => {
        // 隐藏loading
        this.hideLoading();

        console.error("❌ 响应拦截器错误:", {
          url: error.config?.url,
          status: error.response?.status,
          message: error.message,
          data: error.response?.data,
        });

        // 处理不同类型的错误
        this.handleResponseError(error);

        return Promise.reject(error);
      },
    );
  }

  // 处理业务错误
  private handleBusinessError(data: ApiResponse): void {
    const { code, message } = data;

    switch (code) {
      case 401:
        // 未授权，跳转到登录页
        this.redirectToLogin();
        break;
      case 403:
        // 权限不足
        this.showErrorMessage("权限不足，请联系管理员");
        break;
      case 500:
        // 服务器错误
        this.showErrorMessage("服务器内部错误，请稍后重试");
        break;
      default:
        // 其他业务错误
        this.showErrorMessage(message || "操作失败");
    }
  }

  // 处理响应错误
  private handleResponseError(error: AxiosError<ApiResponse>): void {
    const { response, message } = error;

    if (response) {
      const { status, data } = response;

      switch (status) {
        case 401:
          this.showErrorMessage("登录已过期，请重新登录");
          this.redirectToLogin();
          break;
        case 403:
          this.showErrorMessage("权限不足，请联系管理员");
          break;
        case 404:
          this.showErrorMessage("请求的资源不存在");
          break;
        case 500:
          this.showErrorMessage("服务器内部错误，请稍后重试");
          break;
        default:
          this.showErrorMessage(data?.message || `请求失败: ${status}`);
      }
    } else if (error.code === "ECONNABORTED") {
      this.showErrorMessage("请求超时，请检查网络连接");
    } else if (error.code === "NETWORK_ERROR") {
      this.showErrorMessage("网络错误，请检查网络连接");
    } else {
      this.showErrorMessage(message || "请求失败");
    }
  }

  // 获取token
  private getToken(): string | null {
    return localStorage.getItem("token") || sessionStorage.getItem("token");
  }

  // 显示loading
  private showLoading(): void {
    this.loadingCount++;
    // 这里可以集成你的loading组件，比如antd的Spin
    // Spin.setLoadingIndicator(true);
    console.log("🔄 显示loading, 当前loading数量:", this.loadingCount);
  }

  // 隐藏loading
  private hideLoading(): void {
    this.loadingCount = Math.max(0, this.loadingCount - 1);
    if (this.loadingCount === 0) {
      // 这里可以集成你的loading组件，比如antd的Spin
      // Spin.setLoadingIndicator(false);
      console.log("✅ 隐藏loading");
    }
  }

  // 显示错误消息
  private showErrorMessage(message: string): void {
    // 这里可以集成你的消息提示组件，比如antd的message
    // message.error(message);
    console.error("💥 错误消息:", message);
  }

  // 跳转到登录页
  private redirectToLogin(): void {
    // 清除token
    localStorage.removeItem("token");
    sessionStorage.removeItem("token");

    // 跳转到登录页
    // window.location.href = '/login';
    console.log("🔐 跳转到登录页");
  }

  // GET请求
  public get<T = unknown>(
    url: string,
    config?: RequestConfig,
  ): Promise<ApiResponse<T>> {
    return this.axiosInstance.get(url, config);
  }

  // POST请求
  public post<T = unknown>(
    url: string,
    data?: unknown,
    config?: RequestConfig,
  ): Promise<ApiResponse<T>> {
    return this.axiosInstance.post(url, data, config);
  }

  // PUT请求
  public put<T = unknown>(
    url: string,
    data?: unknown,
    config?: RequestConfig,
  ): Promise<ApiResponse<T>> {
    return this.axiosInstance.put(url, data, config);
  }

  // DELETE请求
  public delete<T = unknown>(
    url: string,
    config?: RequestConfig,
  ): Promise<ApiResponse<T>> {
    return this.axiosInstance.delete(url, config);
  }

  // PATCH请求
  public patch<T = unknown>(
    url: string,
    data?: unknown,
    config?: RequestConfig,
  ): Promise<ApiResponse<T>> {
    return this.axiosInstance.patch(url, data, config);
  }

  // 通用请求方法
  public request<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>> {
    return this.axiosInstance.request(config);
  }

  // 设置默认配置
  public setDefaultConfig(config: AxiosRequestConfig): void {
    Object.assign(this.axiosInstance.defaults, config);
  }

  // 设置请求头
  public setHeader(key: string, value: string): void {
    this.axiosInstance.defaults.headers.common[key] = value;
  }

  // 移除请求头
  public removeHeader(key: string): void {
    delete this.axiosInstance.defaults.headers.common[key];
  }
}

// 导出单例实例
export const request = Request.getInstance();

// 导出类型
export type { ApiResponse, RequestConfig };

// 导出便捷方法
export const http = {
  get: request.get.bind(request),
  post: request.post.bind(request),
  put: request.put.bind(request),
  delete: request.delete.bind(request),
  patch: request.patch.bind(request),
  request: request.request.bind(request),
};

export default request;
